package com.qingfeng.medical.biz.order.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qingfeng.medical.base.handler.GeneralAuthException;
import com.qingfeng.medical.base.result.ResultCodeEnum;
import com.qingfeng.medical.biz.order.dao.PaymentInfoMapper;
import com.qingfeng.medical.biz.order.domain.entity.OrderInfo;
import com.qingfeng.medical.biz.order.domain.entity.PaymentInfo;
import com.qingfeng.medical.biz.order.domain.enums.OrderStatusEnum;
import com.qingfeng.medical.biz.order.domain.enums.PaymentStatusEnum;
import com.qingfeng.medical.biz.order.domain.enums.PaymentTypeEnum;
import com.qingfeng.medical.biz.order.service.OrderInfoService;
import com.qingfeng.medical.biz.order.service.PaymentInfoService;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;

/**
 * 支付信息表
 *
 * @author 清风学Java
 * @date 2023-05-11 13:43:46
 */
@Service
public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, PaymentInfo> implements PaymentInfoService {

    @Autowired
    private OrderInfoService orderInfoService;

    /**
     * 保存支付信息
     *
     * @param orderInfo
     * @param wechat
     */
    @Override
    public void savePaymentInfo(OrderInfo orderInfo, PaymentTypeEnum wechat) {
        // 查询是否存在相同的订单
        Integer count = baseMapper.selectCount(
                new LambdaQueryWrapper<PaymentInfo>()
                        .eq(PaymentInfo::getOrderId, orderInfo.getId())
                        .eq(PaymentInfo::getPaymentType, wechat)
        );
        if (count > 0) {
            return;
        }
        // 保存交易记录
        baseMapper.insert(
                PaymentInfo.builder()
                        .orderId(orderInfo.getId())
                        .paymentType(wechat)
                        .outTradeNo(orderInfo.getOutTradeNo())
                        .paymentStatus(PaymentStatusEnum.INIT)
                        .subject(new DateTime(
                                orderInfo.getReserveDate()).toString("yyyy-MM-dd")
                                + "|"
                                + orderInfo.getDepName()
                                + "|"
                                + orderInfo.getPatientName()
                                + "-"
                                + orderInfo.getDoctorName()
                                + "："
                                + orderInfo.getPosition())
                        .totalAmount(orderInfo.getAmount())
                        .build()
        );

    }

    /**
     * 支付成功
     *
     * @param outTradeNo
     * @param paymentType
     * @param paramMap
     */
    @Override
    public void paySuccess(String outTradeNo, PaymentTypeEnum paymentType, Map<String, String> paramMap) {
        //1、根据订单编号得到支付记录
        PaymentInfo paymentInfo = this.getPaymentInfo(outTradeNo, paymentType);
        System.out.println("paymentInfo: " + paymentInfo);
        if (ObjectUtil.isNull(paymentInfo)) {
            throw new GeneralAuthException(ResultCodeEnum.FAIL.getCode(), "无订单信息！");
        }
        if (!paymentInfo.getPaymentStatus().equals(PaymentStatusEnum.INIT)) {
            return;
        }
        //2、更新支付记录信息
        PaymentInfo paymentInfoUpd = PaymentInfo.builder()
                .paymentStatus(PaymentStatusEnum.SUCCESS)
                .tradeNo(paramMap.get("transaction_id"))
                .callbackTime(new Date())
                .callbackContent(paramMap.toString())
                .build();
        System.out.println("paymentInfoUpd: " + paymentInfoUpd);
        this.updatePaymentInfo(outTradeNo, paymentInfoUpd);
        //3、更新订单号得到订单信息
        OrderInfo orderInfo = orderInfoService.getById(paymentInfo.getOrderId());
        orderInfo.setOrderStatus(OrderStatusEnum.SUCCESS);
        System.out.println("orderInfo: " + orderInfo);
        orderInfoService.updateById(orderInfo);
    }

    /**
     * 获取支付记录
     * @param orderId
     * @param paymentType
     * @return
     */
    @Override
    public PaymentInfo getPaymentInfo(Long orderId, PaymentTypeEnum paymentType) {
        return baseMapper.selectOne(
                new LambdaQueryWrapper<PaymentInfo>()
                        .eq(PaymentInfo::getOrderId, orderId)
                        .eq(PaymentInfo::getPaymentType, paymentType)
        );
    }


    /**
     * 获取支付记录
     *
     * @param outTradeNo
     * @param paymentType
     * @return
     */
    private PaymentInfo getPaymentInfo(String outTradeNo, PaymentTypeEnum paymentType) {
        return baseMapper.selectOne(
                new LambdaQueryWrapper<PaymentInfo>()
                        .eq(PaymentInfo::getOutTradeNo, outTradeNo)
                        .eq(PaymentInfo::getPaymentType, paymentType)
        );
    }

    /**
     * 更改支付记录
     *
     * @param outTradeNo
     * @param paymentInfoUpd
     */
    private void updatePaymentInfo(String outTradeNo, PaymentInfo paymentInfoUpd) {
        baseMapper.update(paymentInfoUpd,
                new LambdaQueryWrapper<PaymentInfo>()
                        .eq(PaymentInfo::getOutTradeNo, outTradeNo)
        );
    }
}